/**
 * 
 */
package com.magnusart.scrumppm.model;

import java.util.Collections;
import java.util.List;

/**
 * A class with public values that hold the project data. This class is immutable
 * @author Magnus Andersson
 *
 */
final public class Project implements Comparable<Project>
{

	/**
	 * The name of the project.
	 */
	private final String name;
	
	/**
	 * The description of the project
	 */
	private final String description;

	/**
	 * Describes if this project is closed.
	 */
	private final boolean isDone;
	
	/**
	 * Describes if there are any children to be had.
	 */
	private final boolean hasChildren;
	
	/**
	 * A list of children associated with this project.
	 */
	private final List<Story> children;

	/**
	 * If there are any sprints associated with this project.
	 */
	private final boolean hasSprints;

	/**
	 * A list of sprints.
	 */
	private final List<Sprint> sprints;

	/**
	 * Creates a new project, using the project builder.
	 * @param builder The project builder to be used to build this project.
	 */
	public Project( ProjectBuilder builder ) {
		if( builder.checkStatus() ) {
			this.name = builder.getName();
			this.description = builder.getDescription();
			this.isDone = builder.isDone();
			this.children = builder.getChildren();
			this.sprints = builder.getSprints();
			this.hasChildren = ( children == null ) ? false : true;
			this.hasSprints = ( sprints == null ) ? false : true;
		} else {
			throw new IllegalStateException( "Builder is in an illegal state." );
		}
	}
	
	/**
	 * @return True if there are children associated with this project.
	 */
	public boolean hasStories() {
		return hasChildren;
	}
	
	public boolean hasSprints() {
		return hasSprints;
	}

	/**
	 * Note: the Stories list of children returned are not modifiable.
	 * @return Stories associated with this project. Can be null, see hasChildren.
	 */
	public List<Story> getChildren() {
		return ( children != null ) ? Collections.unmodifiableList( children ) : null;
	}
	

	public List<Sprint> getSprints() {
		return ( sprints != null ) ? Collections.unmodifiableList( sprints ) : null;
	}

	/**
	 * @return The description of the project.
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * @return The project name.
	 */
	public String getName() {
		return name;
	}

	/**
	 * 
	 * @return True if the project is closed
	 */
	public boolean isDone() {
		return isDone;
	}

	@Override
	public boolean equals( Object o ) {
		if( o == this )
			return true;
		if( !( o instanceof Project ) )
			return false;
		
		Project proj = (Project) o;
		return proj.name.equalsIgnoreCase( name );
	}

	@Override
	public int hashCode() {
		int result = 43;
		result += 53 + name.hashCode();
		return result;
	}

	@Override
	public int compareTo( Project proj ) {
		return proj.name.compareToIgnoreCase( name );
	}

	@Override
	public String toString() {
		return "[ Project name: " + name + ", Project description: " + description + ", Closed: " + isDone + ", Has children: " + hasChildren + ", Has sprints: " + hasSprints + " ]";
	}
	
}
